<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
 * FormativeLab
 *
 * An open source application development framework for PHP 5.1.6 or newer
 *
 * @package		FormativeLab
 * @author		FormativeLab Dev Team
 * @copyright	Copyright (c) 2011 - 2013, FormativeLab, Inc.
 * @license		http://www.formativesoft.com/license/
 * @link		http://www.formativesoft.com/
 * @since		Version 2.0
 * @filesource ./application/helpers/model_helper.php
 */

// ------------------------------------------------------------------------

/**
 * FormativeLab Model Helpers
 *
 * @package		FormativeLab
 * @subpackage	Helpers
 * @category	Helpers
 * @author		Formative Soft Ltd
 * @link		http://www.formativesoft.com/
 */

// ------------------------------------------------------------------------

/**
 * Field class for extjs MetaData fields property to generate child Elements
 * for generating XML file by DOMDocument. This class will be helpfull for 
 * generating XML
 **/
 
 if(!class_exists('Field')){
	class Field {
		public $name;
		public $mapping;
		public $type;
		
		/**
		 * __construct() function is an constructor with one required and two 
		 * optional parameters. This constructor is use for initialized class
		 * for generating XML
		 *
		 * @access		public
		 * @property	name
		 * @property	mapping
		 * @property	type
		 */
		public function __construct($name, $mapping = null, $type = 'auto' ){
			$this->name 	= $name;
			$this->mapping	= $mapping ? $mapping : $name;
			$this->type		= $type;
		}
		
	} 
 }
 
// ------------------------------------------------------------------------

/**
 * getMetaData() Takes an array as input parameter return an associative array
 *
 * Lets you determine to use Extjs 4.1 data package json reader. That's why you should
 * made json response as Extjs 4.1 data package. Where is MetaData is optinal issue
 * what type of data transmitted throuht a respnose.
 *
 * @access	public
 * @param	model
 * @return	array
 */
if (!function_exists('getMetaData')){
	function getMetaData($model){
		$metaData = array(
			'idProperty' 	   => getExtjsIdProperty($model),
			'fields'	 	   => getFields($model),
			'totalProperty'    => 'total',
			'successProperty'  => 'success',
			'messageProperty'  => 'message',
			'implicitIncludes' => true,
			'root'			   => 'data'
		);       
        return $metaData;
	}
}

// ------------------------------------------------------------------------

/**
 * getResponseData() - Contains five input parameters. Three parameters mandatory 
 * and rest of two parameters are optinal. Its return an array use for 
 * generating json response for Extjs 4.1 data package.
 *
 * @access	public
 * @param	model
 * @param	records
 * @param	count
 * @param	success
 * @param	message
 * @return  array
 */
if (!function_exists('getResponseData')){
	function getResponseData($model, Array $records, $count, $success=true, $message=''){
		$responseData = array(
			'metaData'	=> getMetaData($model),        
			'data'		=> filterRecords($records),
			'total'		=> $count,
			'success'	=> $success,
			'message'	=> $message
		);
        return $responseData;
	}
}

// ------------------------------------------------------------------------

/**
 * filterRecords() - Contains five input parameters. Three parameters mandatory 
 * and rest of two parameters are optinal. Its return an array use for 
 * generating json response for Extjs 4.1 data package.
 *
 * @access	public
 * @param	records
 * @return  mixed
 */
if (!function_exists('filterRecords')){
	function filterRecords(&$records){
		if(isset($records)){
			foreach($records as $key => &$value){
				if(isset($value)){
					if(is_array($value)){
						filterRecords($value);
					}else if(is_object($value)){
						if(get_class($value) == 'DateTime'){
							if(is_array($records)){
								$records[$key]   = extjsDateFormat($value);
							}else if(is_object($records)){
								$records->{$key} = extjsDateFormat($value);
							}								
						}else{
							filterRecords($value);
						}						
					}
				}
			}
		}		
        return $records;
	}
}

// --------------------------------------------------------------------

/**
 * getField() - Contains tree input parameters. Two parameters are mandatory
 * rest of single parameter is optional
 *
 * Returns only the array for Extjs 4.1 Data Model Field 
 *
 * @access	public
 * @param	name
 * @param	mapping
 * @param	type
 * @return	array
 */
if (!function_exists('getField')){
	function getField($name, $mapping, $type = 'auto'){
		$field = new Field($name, $mapping, $type);		
        return $field; 
	}
}

// --------------------------------------------------------------------

/**
 * getFields() - Contains an input parameter and is mandatory
 *
 * Returns only the array for Extjs 4.1 Data Model Fields 
 *
 * @access	public
 * @param	mapping
 * @return	array
 */
if (!function_exists('getFields')){
	function getFields($model){
		$fields = array();
		if(mappingPropertyExists(get_class($model))){
			$mapping 	= $model->getMapping();
			foreach($mapping as $property => $metaData){
				if(is_array($metaData)){
					$nameKey = 'jsname';
					$typeKey = 'jstype';
					if(arrayKeysExists($metaData, array($nameKey, $typeKey))){
						$jsname 	= $metaData[$nameKey];
						$jstype 	= $metaData[$typeKey];
						$jsmapping  = $property;
						$field		= getField($jsname, $jsmapping, $jstype);
						$fields[]	= $field;
					}
				}
			}
		}else{
			$message = sprintf('Undefined static property [mapping] in class %s', get_class($model));
			trigger_error($message, E_USER_ERROR);
		}
        return $fields; 
	}
}

// --------------------------------------------------------------------

/**
 * getExtjsIdProperty() - Contains an input parameter and is mandatory
 *
 * Returns only the string for Extjs 4.1 Data Model ID Field
 *
 * @access	public
 * @param	model
 * @return	string
 */
if (!function_exists('getExtjsIdProperty')){
	function getExtjsIdProperty($model){
		if(mappingPropertyExists(get_class($model))){
			$mapping 	= $model->getMapping();
			foreach($mapping as $property => $metaData){
				if(is_array($metaData)){
					$fieldKey 	= 'name';
					$nameKey 	= 'jsname';
					if(arrayKeysExists($metaData, array($fieldKey, $nameKey))){
						$dbfield	= $metaData[$fieldKey];
						$jsname 	= $metaData[$nameKey];
						if($dbfield == $model::ID_FIELD){
							return $jsname;
						}
					}
				}
			}
		}else{
			$message = sprintf('Undefined static property [mapping] in class %s', get_class($model));
			trigger_error($message, E_USER_ERROR);
		}
        return 'id'; 
	}
}

// --------------------------------------------------------------------

/**
 * getIdProperty() - Contains an input parameter and is mandatory
 *
 * Returns only the string for model id property; 
 *
 * @access	public
 * @param	model
 * @return	string
 */
if (!function_exists('getIdProperty')){
	function getIdProperty($model){
		$field		= $model::ID_FIELD;
		$property 	= getPropertyByField($model, $field); 
		return $property ? $property : 'id';
	}
}

// --------------------------------------------------------------------

/**
 * getPropertyByField() - Contains two input parameter and is mandatory
 * Returns the property corresponding table field; 
 *
 * @access	public
 * @param	model
 * @param	field
 * @return	string
 */
if (!function_exists('getPropertyByField')){
	function getPropertyByField($model, $field){
		if(mappingPropertyExists(get_class($model))){
			$mapping 	= $model->getMapping();
			foreach($mapping as $property => $metaData){
				if(is_array($metaData)){
					$fieldKey 	= 'name';
					if(arrayKeysExists($metaData, array($fieldKey))){
						$dbfield	= $metaData[$fieldKey];
						if($dbfield == $field){
							return $property;
						}
					}
				}
			}
		}else{
			$message = sprintf('Undefined static property [mapping] in class %s', get_class($model));
			trigger_error($message, E_USER_ERROR);
		}
	}
}

// --------------------------------------------------------------------

/**
 * getFieldByProperty() - Contains two input parameter and is mandatory
 * Returns the property corresponding table field; 
 *
 * @access	public
 * @param	model
 * @param	propertyName
 * @return	string
 */
if (!function_exists('getFieldByProperty')){
	function getFieldByProperty($model, $propertyName){
		if(mappingPropertyExists(get_class($model))){
			$mapping 	= $model->getMapping();
			foreach($mapping as $property => $metaData){
				if($property == $propertyName){
					if(is_array($metaData)){
						$fieldKey 	= 'name';
						if(arrayKeysExists($metaData, array($fieldKey))){
							$dbfield	= $metaData[$fieldKey];
							return $dbfield;
						}
					}
				}
			}
		}else{
			$message = sprintf('Undefined static property [mapping] in class %s', get_class($model));
			trigger_error($message, E_USER_ERROR);
		}
	}
}

// --------------------------------------------------------------------

/**
 * getMappingByField() - Contains two input parameter and is mandatory
 * Returns the property corresponding table field; 
 *
 * @access	public
 * @param	model
 * @param	field
 * @return	string
 */
if (!function_exists('getMappingByField')){
	function getMappingByField($model, $field){
		if(mappingPropertyExists(get_class($model))){
			$mapping 	= $model->getMapping();
			foreach($mapping as $property => $metaData){
				if(is_array($metaData)){
					$fieldKey 	= 'name';
					if(arrayKeysExists($metaData, array($fieldKey))){
						$dbfield	= $metaData[$fieldKey];
						if($dbfield == $field){
							return array($property => $metaData);
						}
					}
				}
			}
		}else{
			$message = sprintf('Undefined static property [mapping] in class %s', get_class($model));
			trigger_error($message, E_USER_ERROR);
		}
	}
}

// --------------------------------------------------------------------

/**
 * getMappingByProperty() - Contains two input parameter and is mandatory
 * Returns the property corresponding table field; 
 *
 * @access	public
 * @param	model
 * @param	propertyName
 * @return	array
 */
if (!function_exists('getMappingByProperty')){
	function getMappingByProperty($model, $propertyName){
		if(mappingPropertyExists(get_class($model))){
			$mapping 	= $model->getMapping();
			foreach($mapping as $property => $metaData){
				if($property == $propertyName){
					return array($property => $metaData);
				}
			}
		}else{
			$message = sprintf('Undefined static property [mapping] in class %s', get_class($model));
			trigger_error($message, E_USER_ERROR);
		}
	}
}

// --------------------------------------------------------------------

/**
 * arrayKeysExists() - Contains two input parameter and both are
 * mandatory
 *
 * Returns bool 
 *
 * @access	public
 * @param	metaData
 * @param	keys
 * @return	bool
 */
if (!function_exists('arrayKeysExists')){
	function arrayKeysExists(Array $metaData, Array $keys){
		foreach($keys as $index => $key){
			if(!array_key_exists($key, $metaData)){
				return false;
			}
		}
        return true; 
	}
}

// --------------------------------------------------------------------

/**
 * hasBelongsToKey() - Contains two input parameters. Two parameters are 
 * mandatory first parameter is array and another one is string 
 *
 * Returns only the bool for Extjs 4.1 if contains belongsToKey
 * it is not set.
 *
 * @access	public
 * @param	records
 * @param	belongsToKey
 * @return	bool
 */
if (!function_exists('hasBelongsToKey')){
	function hasBelongsToKey($records, $belongsToKey){
		$hasRecord   	= is_array($records) && !empty($records);
		$record         = $hasRecord ? $records[0] : null;
		$containsKey    = $record ? array_key_exists($belongsToKey, $record) : false;
		return $containsKey;
    }
}

// --------------------------------------------------------------------

/**
 * resolveMap() - Contains four input parameters. Four parameters are 
 * mandatory first parameter is array,  and rest of tree are string 
 *
 * Returns only the string for Extjs 4.1 Model Field mapping
 *
 * @access	public
 * @param	records
 * @param	belongsToKey
 * @param	field
 * @param	foreignKey
 * @return	string
 */
if (!function_exists('resolveMap')){
	function resolveMap($records, $belongsToKey, $field, $foreignKey){
        $hasKey  = hasBelongsToKey($records, $belongsToKey);
        $mapping = $belongsToKey . $foreignKey;
        return $hasKey ? $mapping : $field;
    }
}

// --------------------------------------------------------------------

/**
 * getBelongsToField() - Contains Five input parameters. Five parameters
 * are mandatory first parameter is array,  and rest of four are string 
 *
 * Returns only the string for Extjs 4.1 Model Field mapping
 *
 * @access	public
 * @param	records
 * @param	belongsToKey
 * @param	field
 * @param	foreignKey
 * @param   type
 * @return	string
 */
if (!function_exists('getBelongsToField')){
	function getBelongsToField($records, $belongsToKey, $field, $foreignKey, $type){
        $mapping = resolveMap($records, $belongsToKey, $field, $foreignKey);
        return  getField($field, $mapping, $type);
    }
}

// --------------------------------------------------------------------

/**
 * decodeModel() - Contains an mandatory input parameter and  this is
 * for Model object 
 *
 * Returns array of Standard Model Object
 *
 * @access	public
 * @param	model
 * @return	array
 */

if (!function_exists('decodeModel')){ 
	function decodeModel(&$model){
		$data 		= array();
		$clazz		= get_class($model);
		if(isset($model)){
			if(mappingPropertyExists($clazz)){
				$mapping   = $model->getMapping();
				foreach($mapping as $property => $metaData){
					$field = $metaData['name'];
					$dtype = $metaData['jstype'];
					if(property_exists($model, $property)){
						if(isset($model->{$property}) && !isLogicalNullKey($metaData, $model->{$property})){
							if($dtype == 'date'){
								$data[$field] = mysqlDateFormat($model->{$property});
							}else {
								$data[$field] = trimString($model->{$property});
							}
						}
					}
				}
			}else{
				$message = sprintf('Undefined static property [mapping] in class %s', get_class($model));
				trigger_error($message, E_USER_ERROR);
			}
		}
		return $data;
	}
	
}

// --------------------------------------------------------------------

/**
 * encodeModel() - Contains two mandatory input parameters. First one is
 * entity and last one is Array 
 *
 * Returns array of Standard Model Object
 *
 * @access	public
 * @param	entity
 * @param	data
 * @return	object
 */

if (!function_exists('encodeModel')){
	function encodeModel(&$entity, $data){
		$model 		= null;
		$clazz		= get_class($entity);

		if(mappingPropertyExists($clazz)){
			if(isset($data)){
				$model 		= new $clazz();
				$mapping 	= $model->getMapping();
				foreach($mapping as $property => $metaData){
					$field = $metaData['name'];
					$dtype = $metaData['jstype'];
					if(array_key_exists($field, $data)){
						if(isset($data->{$field})){
							switch($dtype){								
								case 'int'		: $model->{$property} = intval($data->{$field}); 		break;
								case 'auto'		: $model->{$property} = strval($data->{$field});		break;
								case 'date'		: $model->{$property} = parseDate($data->{$field}); 	break;
								case 'float'	: $model->{$property} = doubleval($data->{$field}); 	break;								
								case 'string'	: $model->{$property} = trimString($data->{$field});	break;
								case 'boolean'	: $model->{$property} = boolval($data->{$field}); 		break;								
							}
						}
					}			 
				}
			}
		}else{
			$message = sprintf('Undefined static property [mapping] in class %s', $clazz);
			trigger_error($message, E_USER_ERROR);
		}
		return $model;
	}
}

// --------------------------------------------------------------------

/**
 * mergeEntity() with two required parameters of entity standard 
 * entity class object use for merge value of persis object
 *
 * Returns object
 *
 * @access	public
 * @param	entity
 * @param	persis
 * @return  object 
 */

if (!function_exists('mergeEntity')){
	function mergeEntity(&$entity, &$persis){
		$clazz		= get_class($entity);
		if(mappingPropertyExists($clazz)){
			if(isset($persis)){
				$mapping 	= $entity->getMapping();
				foreach($mapping as $property => $metaData){
					if(property_exists($persis, $property)){
						$entity->{$property}	= $persis->{$property};
					}			 
				}
			}
		}else{
			$message = sprintf('Undefined static property [mapping] in class %s', $clazz);
			trigger_error($message, E_USER_ERROR);
		}		
		return $entity;
	}
}

// --------------------------------------------------------------------

/**
 * isDirtyEntity() with two required parameters of entity standard 
 * entity class object use for merge value of persis object
 *
 * Returns object
 *
 * @access	public
 * @param	entity
 * @param	persis
 * @return  bool 
 */

if (!function_exists('isDirtyEntity')){
	function isDirtyEntity(&$entity, &$persis){
		$clazz		= get_class($entity);
		if(mappingPropertyExists($clazz)){
			if(isset($persis)){
				$mapping 	= $entity::$mapping;
				foreach($mapping as $property => $metaData){
					if(property_exists($persis, $property)){
						$evalue	= $entity->{$property};
						$pvalue = $persis->{$property};
						
						$evalue = trimString($evalue);
						$pvalue = trimString($pvalue);
						
						if($evalue	!= $pvalue){
							return true;
						}
					}			 
				}
			}
		}else{
			$message = sprintf('Undefined static property [mapping] in class %s', $clazz);
			trigger_error($message, E_USER_ERROR);
		}		
		return false;
	}
}

// --------------------------------------------------------------------

/**
 * exampleQueryBuilder() - Contains two mandatory input parameters. First
 * one is stardard database object and another one is standard 
 * Model/Entity/Domain class
 *
 * Returns void
 *
 * @access	public
 * @param	db
 * @param	model
 * @return	void
 */

if (!function_exists('exampleQueryBuilder')){
	function exampleQueryBuilder(&$model){
		$where			= array();
		if(isset($model)){
			$clazz		= get_class($model);		
			if(mappingPropertyExists($clazz)){
				$mapping   = $model->getMapping();
				foreach($mapping as $property => $metaData){
					$field = $metaData['name'];
					if(property_exists($model, $property)){
						$operator = resolveComparativeOperator($model->{$property});
						if($operator){
							$value	= resolveComparativeValue($model->{$property});
							$value	= $model->db->escape($value);
							switch($operator){
								case 'eq'	: $where[$field] = array(
									'operator'	=> $operator,
									'value'		=> $value
								); break;
								case 'like' : $where[$field] = array(
									'operator'	=> $operator,
									'value'		=> $value,
									'match'		=> 'after'
								); break;						
							}
						}					
					}		 
				}			
			}else{
				$message = sprintf('Undefined static property [mapping] in class %s', $clazzName);
				trigger_error($message, E_USER_ERROR);
			}
		}
		return $where;
	}
}

// --------------------------------------------------------------------

/**
 * resolveComparativeOperator() - Contains an mandatory input parameters.
 * Which one is standard Model/Domain/Entity class property
 *
 * Returns name of RDMS comparative Operator
 *
 * @access	public
 * @param	type
 * @return	string
 */

if (!function_exists('resolveComparativeOperator')){
	function resolveComparativeOperator($value){
		if(isset($value)){
			if(!is_object($value)){
				$type = gettype($value);
				switch($type){
					case 'integer'	:
					case 'double' 	:
					case 'boolean'	: return 'eq';   break;
					case 'string' 	: return 'like'; break;
					default			: return false;
				}
			}else{
				$clazzName = get_class($value);
				if($clazzName == 'DateTime'){
					return 'eq';
				}
			}
		}
		return false;
	}
}

// --------------------------------------------------------------------

/**
 * resolveComparativeValue() - Contains an mandatory input parameters.
 * Which one is standard Model/Domain/Entity class property
 *
 * Returns name of RDMS comparative Operator
 *
 * @access	public
 * @param	type
 * @return	string
 */

if (!function_exists('resolveComparativeValue')){
	function resolveComparativeValue($value){
		if(isset($value)){
			if(!is_object($value)){
				$type = gettype($value);
				return $value;
			}else{
				$clazzName = get_class($value);
				if($clazzName == 'DateTime'){
					return mysqlDateFormat($value);
				}
			}
		}
		return false;
	}
}

// --------------------------------------------------------------------

/**
 * parseDate() - Contains an mandatory input parameters.
 * Which one is string value
 *
 * Returns DateTime
 *
 * @access	public
 * @param	value
 * @return	DateTime
 */

if (!function_exists('parseDate')){
	function parseDate($value){
		if(isset($value) && isValidDate($value)){
			$date	= new DateTime($value);
			return $date;
		}
	}
}

// --------------------------------------------------------------------

/**
 * mysqlDateFormat() - Contains an mandatory input parameters.
 * Which one is string value
 *
 * Returns string
 *
 * @access	public
 * @param	value
 * @return	string
 */

if (!function_exists('mysqlDateFormat')){
	function mysqlDateFormat(DateTime $value){
		if(isset($value)){
			return $value->format('Y-m-d H:i:s');
		}
	}
}

// --------------------------------------------------------------------

/**
 * extjsDateFormat() - Contains an mandatory input parameters.
 * Which one is string value
 *
 * Returns string
 *
 * @access	public
 * @param	value
 * @return	string
 */

if (!function_exists('extjsDateFormat')){
	function extjsDateFormat(DateTime $value){
		if(isset($value)){
			return $value->format('Y-m-d\\TH:i:s\\Z');
		}
	}
}


// --------------------------------------------------------------------

/**
 * isValidDate() - Contains an mandatory input parameters.
 * Which one is string value
 *
 * Returns bool
 *
 * @access	public
 * @param	value
 * @return	bool
 */

if (!function_exists('isValidDate')){
	function isValidDate($value){
		$patterns = array(			
			'local_date_deshas'			=> '/^(3[0-1]|[1-2][0-9]|0[1-9])-(1[0-2]|0[1-9])-[\\d]{4}$/',
			'local_date_forward_slash'	=> '/^(3[0-1]|[1-2][0-9]|0[1-9])\/(1[0-2]|0[1-9])\/[\\d]{4}$/',
			'extjs_date_time'			=> '/^[\\d]{4}-(1[0-2]|0[1-9])-(3[0-1]|[1-2][0-9]|0[1-9])T(2[0-3]|[0-1][0-9]):([0-5][0-9]):([0-5][0-9])Z$/',
			'mysql_date_time'			=> '/^[\\d]{4}-(1[0-2]|0[1-9])-(3[0-1]|[1-2][0-9]|0[1-9]) (2[0-3]|[0-1][0-9]):([0-5][0-9]):([0-5][0-9])$/',
			'mysql_date'				=> '/^[\\d]{4}-(1[0-2]|0[1-9])-(3[0-1]|[1-2][0-9]|0[1-9])$/'					
		);
		foreach($patterns as $key => $pattern){
			if(preg_match($pattern, $value)){
				return true;
			}
		}
		return false;
	}
}

// --------------------------------------------------------------------

/**
 * hasMany() - Contains an mandatory input parameter. This parameter
 * is an Standard Entity/Model object. This parameter like in out 
 * parameter. This function only modify the object property only. 
 * The existing property will be changed as the belongs to associations.
 *
 * Returns array of Standard Model Object
 *
 * @access	public
 * @param	model
 * @return	object
 */

if (!function_exists('hasMany')){
	function hasMany(&$model){
		if(isset($model) && hasManyPropertyExists(get_class($model))){
			$hasMany	= $model::$hasMany;
			foreach($hasMany as $property => $association){
				$clazz		= $association['clazz'];
				$reference	= $association['reference'];
				$mapedBy	= $association['mapedBy'];
				
				if(property_exists($model, $property)){
					$model->{$property} = array(); //list hasMany
				}
			}
		}
		return $model;
	}
}

// --------------------------------------------------------------------

/**
 * hasOne() - Contains an mandatory input parameter. This parameter
 * is an Standard Entity/Model object. This parameter like in out 
 * parameter. This function only modify the object property only. 
 * The existing property will be changed as the belongs to associations.
 *
 * Returns array of Standard Model Object
 *
 * @access	public
 * @param	model
 * @return	object
 */

if (!function_exists('hasOne')){
	function hasOne(&$model){
		if(isset($model) && hasOnePropertyExists(get_class($model))){
			$hasOne	= $model::$hasOne;
			foreach($hasOne as $property => $association){
				$clazz		= $association['clazz'];
				$reference	= $association['reference'];
				$mapedBy	= $association['mapedBy'];
				
				if(property_exists($model, $property)){
					$model->{$property} = array(); //list hasOne
				}
			}
		}
		return $model;
	}
}

// --------------------------------------------------------------------

/**
 * belongsTo() - Contains an mandatory input parameter. This parameter
 * is an Standard Entity/Model object. This parameter like in out 
 * parameter. This function only modify the object property only. 
 * The existing property will be changed as the belongs to associations.
 *
 * Returns array of Standard Model Object
 *
 * @access	public
 * @param	model
 * @return	object
 */

if (!function_exists('belongsTo')){
	function belongsTo(&$model){
		if(isset($model)){
			$belongsTo		= $model->getBelongsTo();			
			foreach($belongsTo as $property => $association){
				$clazz		= $association['clazz'];
				$reference	= $association['reference'];
				$mapedBy	= $association['mapedBy'];
				
				if(property_exists($model, $property)){
					$model->{$property} = array(); //list belongsTo
				}
			}
		}
		return $model;
	}
}

// --------------------------------------------------------------------

/**
 * hasStaticProperty() - Contains two mandatory input parameter. First
 * is for class name and another one is for static property name. This
 * method will return bool value
 *
 * Returns bool
 *
 * @access	public
 * @param	clazzName
 * @param	propertyName
 * @return	bool
 */

if (!function_exists('hasStaticProperty')){
	function hasStaticProperty($clazzName, $propertyName){
		if(isset($clazzName) && isset($propertyName)){
			$staticProperties = get_class_vars($clazzName);
			return array_key_exists($propertyName, $staticProperties);			
		}
		return false;
	}
}

// --------------------------------------------------------------------

/**
 * mappingPropertyExists() - Contains an mandatory input parameter. Which
 * one use for class name. This method will return bool value
 *
 * Returns bool
 *
 * @access	public
 * @param	clazzName
 * @return	bool
 */

if (!function_exists('mappingPropertyExists')){
	function mappingPropertyExists($clazzName){
		return hasStaticProperty($clazzName, 'mapping');
	}
}

// --------------------------------------------------------------------

/**
 * hasManyPropertyExists() - Contains an mandatory input parameter. Which
 * one use for class name. This method will return bool value
 *
 * Returns bool
 *
 * @access	public
 * @param	clazzName
 * @return	bool
 */

if (!function_exists('hasManyPropertyExists')){
	function hasManyPropertyExists($clazzName){
		return hasStaticProperty($clazzName, 'hasMany');
	}
}

// --------------------------------------------------------------------

/**
 * hasOnePropertyExists() - Contains an mandatory input parameter. Which
 * one use for class name. This method will return bool value
 *
 * Returns bool
 *
 * @access	public
 * @param	clazzName
 * @return	bool
 */

if (!function_exists('hasOnePropertyExists')){
	function hasOnePropertyExists($clazzName){
		return hasStaticProperty($clazzName, 'hasOne');
	}
}

// --------------------------------------------------------------------

/**
 * belongsToPropertyExists() - Contains an mandatory input parameter. Which
 * one use for class name. This method will return bool value
 *
 * Returns bool
 *
 * @access	public
 * @param	clazzName
 * @return	bool
 */

if (!function_exists('belongsToPropertyExists')){
	function belongsToPropertyExists($clazzName){
		return hasStaticProperty($clazzName, 'belongsTo');
	}
}

// --------------------------------------------------------------------

/**
 * constraintsPropertyExists() - Contains an mandatory input parameter. Which
 * one use for class name. This method will return bool value
 *
 * Returns bool
 *
 * @access	public
 * @param	clazzName
 * @return	bool
 */

if (!function_exists('constraintsPropertyExists')){
	function constraintsPropertyExists($clazzName){
		return hasStaticProperty($clazzName, 'constraints');
	}
}

// --------------------------------------------------------------------

/**
 * modelsPropertyExists() - Contains an mandatory input parameter. Which
 * one use for class name. This method will return bool value
 *
 * Returns bool
 *
 * @access	public
 * @param	clazzName
 * @return	bool
 */

if (!function_exists('modelsPropertyExists')){
	function modelsPropertyExists($clazzName){
		return hasStaticProperty($clazzName, 'models');
	}
}

// --------------------------------------------------------------------

/**
 * trimString() - Contains an mandatory input parameter. Which one use to
 * trim string only
 *
 * Returns mixed
 *
 * @access	public
 * @param	string
 * @return	mixed
 */

if (!function_exists('trimString')){
	function trimString($string){
		if(is_string($string)){
			$value = trim($string);
			return empty($value) ? NULL : $value;
		}
		//return is_string($string) ? trim($string) : $string;
		return $string;
	}
}

// --------------------------------------------------------------------

/**
 * resolveModule() - Contains an mandatory input parameter. Which one use to
 * resolve module name of domain/model/entity
 *
 * Returns string
 *
 * @access	public
 * @param	clazz
 * @return	string
 */

if (!function_exists('resolveModule')){
	function resolveModule($clazz){
		$pattern	= '/^M[0-9]{2}[B|I|Q|R|S|T]{1}[0-9]{6}$/';
		if(preg_match($pattern, $clazz)){
			$prefix = substr($clazz, 0, 3);
			return sprintf('%s001',$prefix);
		}
	}
}

// --------------------------------------------------------------------

/**
 * resolveSubmodule() - Contains an mandatory input parameter. Which one use to
 * resolve submodule name of domain/model/entity
 *
 * Returns string
 *
 * @access	public
 * @param	clazz
 * @return	string
 */

if (!function_exists('resolveSubmodule')){
	function resolveSubmodule($clazz){
		$pattern	= '/^M[0-9]{2}[B|I|Q|R|S|T]{1}[0-9]{6}$/';
		if(preg_match($pattern, $clazz)){
			$prefix = substr($clazz, 0, 4);
			return sprintf('%s001',$prefix);
		}
	}
}

// --------------------------------------------------------------------

/**
 * loadModel() - Contains an mandatory input parameter. Which one use to
 * resolve load domain/model/entity
 *
 * Returns string
 *
 * @access	public
 * @param	clazz
 * @return	string
 */

if (!function_exists('loadModel')){
	function loadModel($clazz){
		$codeIgniter	= &get_instance();
		$classes		= is_array($clazz) ? $clazz : array($clazz);
		foreach($classes as $index => $model){
			$module			= strtolower(resolveModule($model));
			$submodule		= strtolower(resolveSubmodule($model));
			$package		= sprintf('%s/%s/%s', $module, $submodule, $model);
			$codeIgniter->load->model($package);
		}
	}
}

// --------------------------------------------------------------------

/**
 * loadLanguage() - Contains an mandatory input parameter. Which one use to
 * load language of domain/model/entity
 *
 * Returns string
 *
 * @access	public
 * @param	clazz
 * @param	local
 * @return	string
 */

if (!function_exists('loadLanguage')){
	function loadLanguage($class, $local = 'english'){
		$codeIgniter	= &get_instance();
		$clazz			= strtolower($class);
		$module			= strtolower(resolveModule($class));
		$submodule		= strtolower(resolveSubmodule($class));
		$package		= sprintf('models/%s/%s/%s', $module, $submodule, $clazz); 
		$codeIgniter->lang->load($package, $local);
	}
}

// --------------------------------------------------------------------

/**
 * parseUnicodedHexString() - Contains an mandatory input parameter. Which one use is
 * unicoded hex string and will be parsed into string. This method use to load lang
 * from language.
 *
 * Returns string
 *
 * @access	public
 * @param	unicodedHexString
 * @return	string
 */

if (!function_exists('parseUnicodeHexString')){
	function parseUnicodedHexString($unicodedHexString){
		$unicodedHexString = is_null($unicodedHexString) ? '' : $unicodedHexString;
		return json_decode("\"{$unicodedHexString}\"");
	}
}

// --------------------------------------------------------------------

/**
 * isForeignKey() - to cechk the entity/model/domain property is a foreign key field.
 * this method use to detect foreign property.
 *
 * Returns Boolean
 *
 * @access	public
 * @param	metaData
 * @return	bool
 */

if (!function_exists('isForeignKey')){
	function isForeignKey($metaData){
		if(array_key_exists('name', $metaData)){
			$pattern	= '/^k_[a-z\d\_ ]{2,45}$/';
			$field 		= $metaData['name'];
			return preg_match($pattern, $field);
		}
	}
}

// --------------------------------------------------------------------

/**
 * isNullable() - to cechk the entity/model/domain property is a nullable field.
 * this method use to detect nullable property.
 *
 * Returns Boolean
 *
 * @access	public
 * @param	metaData
 * @return	bool
 */

if (!function_exists('isNullable')){
	function isNullable($metaData){
		if(array_key_exists('nullable', $metaData)){
			return $metaData['nullable'];
		}
	}
}

// --------------------------------------------------------------------

/**
 * isNullableKey() - to cechk the entity/model/domain property is a nullable key field.
 * this method use to detect nullable key property.
 *
 * Returns Boolean
 *
 * @access	public
 * @param	metaData
 * @return	bool
 */

if (!function_exists('isNullableKey')){
	function isNullableKey($metaData){
		return isForeignKey($metaData) && isNullable($metaData);
	}
}

// --------------------------------------------------------------------

/**
 * isLogicalNull() - to check the entity/model/domain property is logically null. to 
 * peform CRUD operation, specially for create and update.
 *
 * Returns Boolean
 *
 * @access	public
 * @param	metaData
 * @return	bool
 */

if (!function_exists('isLogicalNull')){
	function isLogicalNull($value){
		$value		= trimString($value);
		return empty($value)|| $value == 0 ;
	}
}

// --------------------------------------------------------------------

/**
 * isLogicalNullKey() - to check the entity/model/domain foreign key property is
 * logically null, to peform CRUD operation, specially for create and update.
 *
 * Returns Boolean
 *
 * @access	public
 * @param	metaData
 * @param	value
 * @return	bool
 */

if (!function_exists('isLogicalNullKey')){
	function isLogicalNullKey($metaData, $value){
		return isNullableKey($metaData) && isLogicalNull($value);
	}
}

// --------------------------------------------------------------------

/**
 * filterForeignProperty() - to filter the entity/model/domain foreign key property.
 * this method use to nullify key property.
 *
 * Returns Boolean
 *
 * @access	public
 * @param	metaData
 * @param	model
 * @param	property
 * @return	bool
 */

if (!function_exists('filterForeignProperty')){
	function filterForeignProperty($metaData, &$model, $property){
		if(isNullableKey($metaData) && isLogicalNull($model->{$property})){
			$model->{$property} = NULL;
			return true;
		}
	}
}

/* End of file model_helper.php */
/* Location: ./application/helpers/model_helper.php */